1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing.testers;
18
19 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22 import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
24 import static java.util.Collections.singletonList;
25
26 import com.google.common.annotations.GwtCompatible;
27 import com.google.common.annotations.GwtIncompatible;
28 import com.google.common.collect.testing.AbstractMapTester;
29 import com.google.common.collect.testing.Helpers;
30 import com.google.common.collect.testing.MinimalCollection;
31 import com.google.common.collect.testing.features.CollectionSize;
32 import com.google.common.collect.testing.features.MapFeature;
33
34 import java.lang.reflect.Method;
35 import java.util.Collections;
36 import java.util.ConcurrentModificationException;
37 import java.util.Iterator;
38 import java.util.LinkedHashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Map.Entry;
42
43
44
45
46
47
48
49
50
51 @SuppressWarnings("unchecked")
52 @GwtCompatible(emulated = true)
53 public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
54 private List<Entry<K, V>> containsNullKey;
55 private List<Entry<K, V>> containsNullValue;
56
57 @Override public void setUp() throws Exception {
58 super.setUp();
59 containsNullKey = singletonList(entry(null, samples.e3.getValue()));
60 containsNullValue = singletonList(entry(samples.e3.getKey(), null));
61 }
62
63 @MapFeature.Require(SUPPORTS_PUT)
64 public void testPutAll_supportedNothing() {
65 getMap().putAll(emptyMap());
66 expectUnchanged();
67 }
68
69 @MapFeature.Require(absent = SUPPORTS_PUT)
70 public void testPutAll_unsupportedNothing() {
71 try {
72 getMap().putAll(emptyMap());
73 } catch (UnsupportedOperationException tolerated) {
74 }
75 expectUnchanged();
76 }
77
78 @MapFeature.Require(SUPPORTS_PUT)
79 public void testPutAll_supportedNonePresent() {
80 putAll(createDisjointCollection());
81 expectAdded(samples.e3, samples.e4);
82 }
83
84 @MapFeature.Require(absent = SUPPORTS_PUT)
85 public void testPutAll_unsupportedNonePresent() {
86 try {
87 putAll(createDisjointCollection());
88 fail("putAll(nonePresent) should throw");
89 } catch (UnsupportedOperationException expected) {
90 }
91 expectUnchanged();
92 expectMissing(samples.e3, samples.e4);
93 }
94
95 @MapFeature.Require(SUPPORTS_PUT)
96 @CollectionSize.Require(absent = ZERO)
97 public void testPutAll_supportedSomePresent() {
98 putAll(MinimalCollection.of(samples.e3, samples.e0));
99 expectAdded(samples.e3);
100 }
101
102 @MapFeature.Require({ FAILS_FAST_ON_CONCURRENT_MODIFICATION,
103 SUPPORTS_PUT })
104 @CollectionSize.Require(absent = ZERO)
105 public void testPutAllSomePresentConcurrentWithEntrySetIteration() {
106 try {
107 Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
108 putAll(MinimalCollection.of(samples.e3, samples.e0));
109 iterator.next();
110 fail("Expected ConcurrentModificationException");
111 } catch (ConcurrentModificationException expected) {
112
113 }
114 }
115
116 @MapFeature.Require(absent = SUPPORTS_PUT)
117 @CollectionSize.Require(absent = ZERO)
118 public void testPutAll_unsupportedSomePresent() {
119 try {
120 putAll(MinimalCollection.of(samples.e3, samples.e0));
121 fail("putAll(somePresent) should throw");
122 } catch (UnsupportedOperationException expected) {
123 }
124 expectUnchanged();
125 }
126
127 @MapFeature.Require(absent = SUPPORTS_PUT)
128 @CollectionSize.Require(absent = ZERO)
129 public void testPutAll_unsupportedAllPresent() {
130 try {
131 putAll(MinimalCollection.of(samples.e0));
132 } catch (UnsupportedOperationException tolerated) {
133 }
134 expectUnchanged();
135 }
136
137 @MapFeature.Require({SUPPORTS_PUT,
138 ALLOWS_NULL_KEYS})
139 public void testPutAll_nullKeySupported() {
140 putAll(containsNullKey);
141 expectAdded(containsNullKey.get(0));
142 }
143
144 @MapFeature.Require(value = SUPPORTS_PUT,
145 absent = ALLOWS_NULL_KEYS)
146 public void testPutAll_nullKeyUnsupported() {
147 try {
148 putAll(containsNullKey);
149 fail("putAll(containsNullKey) should throw");
150 } catch (NullPointerException expected) {
151 }
152 expectUnchanged();
153 expectNullKeyMissingWhenNullKeysUnsupported(
154 "Should not contain null key after unsupported " +
155 "putAll(containsNullKey)");
156 }
157
158 @MapFeature.Require({SUPPORTS_PUT,
159 ALLOWS_NULL_VALUES})
160 public void testPutAll_nullValueSupported() {
161 putAll(containsNullValue);
162 expectAdded(containsNullValue.get(0));
163 }
164
165 @MapFeature.Require(value = SUPPORTS_PUT,
166 absent = ALLOWS_NULL_VALUES)
167 public void testPutAll_nullValueUnsupported() {
168 try {
169 putAll(containsNullValue);
170 fail("putAll(containsNullValue) should throw");
171 } catch (NullPointerException expected) {
172 }
173 expectUnchanged();
174 expectNullValueMissingWhenNullValuesUnsupported(
175 "Should not contain null value after unsupported " +
176 "putAll(containsNullValue)");
177 }
178
179 @MapFeature.Require(SUPPORTS_PUT)
180 public void testPutAll_nullCollectionReference() {
181 try {
182 getMap().putAll(null);
183 fail("putAll(null) should throw NullPointerException");
184 } catch (NullPointerException expected) {
185 }
186 }
187
188 private Map<K, V> emptyMap() {
189 return Collections.emptyMap();
190 }
191
192 private void putAll(Iterable<Entry<K, V>> entries) {
193 Map<K, V> map = new LinkedHashMap<K, V>();
194 for (Entry<K, V> entry : entries) {
195 map.put(entry.getKey(), entry.getValue());
196 }
197 getMap().putAll(map);
198 }
199
200
201
202
203
204
205
206
207 @GwtIncompatible("reflection")
208 public static Method getPutAllNullKeyUnsupportedMethod() {
209 return Helpers.getMethod(MapPutAllTester.class, "testPutAll_nullKeyUnsupported");
210 }
211 }